package main

import (
	"epg/api"
	"epg/jmconf"
	"epg/server"
	"epg/stats/pprof"
	"epg/utils"
	"flag"
	"fmt"
	"os"
	"path"
	"strings"
	"syscall"

	"github.com/zeast/logs"
)

var (
	flagConfig = flag.String("config", "", "The config file path.")

	//Distributed Configuration System
	flagDcsType    = flag.String("dcs_type", "consul", "Distributed Configuration System(DCS) type: consul, etcd, zk.")
	flagDcsAddr    = flag.String("dcs_addr", "127.0.0.1:8500", "DCS addrs multi addr use ',' to split.")
	flagDcsPath    = flag.String("dcs_path", "conf/epg/master", "The Nodes config in DCS.")
	flagDcsDC      = flag.String("dcs_dc", "dc1", "Which data center will use, when query in DCS.")
	flagDcsTimeout = flag.Int("dcs_timeout", 10, "DCS timeout")
	flagDcsToken   = flag.String("dcs_token", "", "DCS auth token")

	//服务参数配置
	flagListen   = flag.String("listen", ":6603", "Server listen addr ")
	flagAPISrv   = flag.String("api", ":6604", "API Server listen addr")
	flagHostName = flag.String("host_name", "", "The host name of the server.")
	flagRole     = flag.String("role", "master", "The server running mode. master:will check the database unique; slave: nothing to do.")
	flagLogPath  = flag.String("log_path", "/home/logs/epg/epg.log", "EPG Server Log Path, make sure the dir can write.")
	flagLogLevel = flag.String("log_level", "debug", "Log Level: debug, info, warn, error, fatal")

	//性能监控,统计
	flagStatsD = flag.String("statsd", "127.0.0.1:8125", "StatsD addr")

	flagVersion = flag.Bool("version", false, "Display build version and exit.")
)

func main() {
	flag.Parse()

	//print banner
	if *flagVersion {
		ver := displayVersion()
		fmt.Println(ver)
		os.Exit(0)
	}

	//use config file or cmd argv
	if *flagConfig != "" {
		jmconf.Init(*flagConfig)
	} else {
		cfg := jmconf.LocalCfg{
			Listen:    *flagListen,
			APIServer: *flagAPISrv,
			HostName:  *flagHostName,
			StatsD:    *flagStatsD,
			Role:      *flagRole,
			LogPath:   *flagLogPath,
			LogLvl:    *flagLogLevel,
			DisCfg: jmconf.DisCfg{
				Type:       *flagDcsType,
				Addrs:      strings.Split(*flagDcsAddr, ","),
				Path:       *flagDcsPath,
				Timeout:    int64(*flagDcsTimeout),
				Token:      *flagDcsToken,
				DataCenter: *flagDcsDC,
			},
		}
		jmconf.Cfg = cfg
	}
	if jmconf.Cfg.HostName == "" {
		jmconf.Cfg.HostName, _ = os.Hostname()
	}

	//log to file
	if len(jmconf.Cfg.LogPath) > 0 {
		w, err := logs.NewFileWriter(logs.FileConfig{
			Name:  path.Join(jmconf.Cfg.LogPath + "epg.log"),
			Perm:  "0644",
			Async: true,
			Rotate: &logs.Rotate{
				Daily:   true,
				MaxSize: 1024 * 1024 * 1024, //1G
				MaxDays: 3,
				Perm:    "0444",
			},
		})

		if err != nil {
			fmt.Println(err)
			os.Exit(-1)
		}
		logs.SetBaseWriter(w)
		logs.LogFuncCall(true)
		logs.SetLogLevelStr(jmconf.Cfg.LogLvl)

		s, err := utils.NewSender("epg", jmconf.Cfg.UmsAgentAddr)
		if err != nil {
			logs.Fatal("初始化 ums 错误, %s", err)
		}

		logs.AddWriter(logs.LevelError, s)
	}

	//check limit
	limit := new(syscall.Rlimit)
	if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, limit); err != nil {
		logs.Fatal(err)
	}

	if limit.Cur < uint64(jmconf.Cfg.MaxOpenFiles) {
		limit.Cur = uint64(jmconf.Cfg.MaxOpenFiles)
		limit.Max = uint64(jmconf.Cfg.MaxOpenFiles)
		if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, limit); err != nil {
			logs.Fatal(err)
		}
	}

	//start pprof
	pprof.Start()

	//api service
	if jmconf.Cfg.APIServer != "" {
		api.StartService(jmconf.Cfg.APIServer)
	}

	//new and run server
	logs.Error(server.New().Run())
}
